package io.renren.modules.sys.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class FilesUtil {

	/**
	 * 创建文件
	 *
	 *            目录路径
	 * @param fileName
	 * @return
	 * @throws IOException
	 *             /
	 */
	public static File createFile(String fileName) throws IOException {
		File file = new File(fileName);
		file.createNewFile();
		return file;
	}

	/**
	 * 创建目录
	 *
	 * @param dir
	 *            目录路径
	 * @return
	 */
	public static File creatDir(String dir) {
		File dirFile = new File(dir);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}
		return dirFile;
	}

	/**
	 * 判断文件夹是否存在
	 *
	 *            目录路径
	 * @param fileName
	 *            文件名称
	 * @return
	 */
	public static boolean isFileExist(String fileName) {
		File file = new File(fileName);
		if (!file.exists()){
			return false;
		}
		if (file.isDirectory()){
			return false;
		}
		return true;
	}


	/**
	 * 将一个字节数组数据写入到文件中
	 * @param fileName 文件全路径名
	 * @param bytes
	 * @return
	 */
	public static boolean write(String fileName, byte[] bytes) {

		if (bytes == null) {
			return false;
		}

		OutputStream output = null;
		try {
			File file = null;
			file = createFile(fileName);
			output = new BufferedOutputStream(new FileOutputStream(file));
			output.write(bytes);
			output.flush();
			return true;
		} catch (IOException e1) {
			e1.printStackTrace();
		} finally {
			try {
				if (output != null) {
					output.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	/***
	 * 读取文件，并且以字节流返回
	 *
	 * @param fileName
	 * @return
	 */
	public static byte[] read(String fileName) {
		File file = new File( fileName);
		if (!file.exists()) {
			return null;
		}
		InputStream inputStream = null;
		try {
			inputStream = new BufferedInputStream(new FileInputStream(file));
			byte[] data = new byte[inputStream.available()];
			inputStream.read(data);
			return data;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 复制文件或者目录,复制前后文件完全一样。
	 *
	 * @param resFilePath
	 *            源文件路径
	 * @param distFolder
	 *            目标文件夹
	 * @IOException 当操作发生异常时抛出
	 */
	public static void copyFile(String resFilePath, String distFolder)
			throws IOException {
		File resFile = new File(resFilePath);
		File distFile = new File(distFolder);
		if (resFile.isDirectory()) {
			FileUtils.copyDirectory(resFile, distFile);
		} else if (resFile.isFile()) {
			FileUtils.copyFileToDirectory(resFile, distFile, true);
		}
	}

	/**
	 * 复制文件或者目录,复制前后文件完全一样。
	 *
	 *            源文件路径
	 *            目标文件夹
	 * @IOException 当操作发生异常时抛出
	 */
	public static void copyFile(File src, File des)
			throws IOException {
		if (src.isDirectory()) {
			FileUtils.copyDirectory(src, des);
		} else if (src.isFile()) {
			FileUtils.copyFileToDirectory(src, des, true);
		}
	}

	/**
	 * 拷贝文件到目标文件，如果目标路径不存在，自动创建
	 * @param srcFilePath 源文件
	 * @param destFilePath 目标文件
	 * @throws IOException
	 */
	public static void copyFile2File(String srcFilePath, String destFilePath) throws IOException {
		File srcFile = new File(srcFilePath);
		File destFile = new File(destFilePath);

		FileUtils.copyFile(srcFile, destFile);
	}

	/**
	 * 删除一个文件或者目录
	 *
	 * @param targetPath
	 *            文件或者目录路径
	 * @IOException 当操作发生异常时抛出
	 */
	public static void deleteFile(String targetPath) throws IOException {
		File targetFile = new File(targetPath);
		if (targetFile.isDirectory()) {
			FileUtils.deleteDirectory(targetFile);
		} else if (targetFile.isFile()) {
			targetFile.delete();
		}
	}

	/**
	 * 判断一个文件是否存在
	 *
	 * @param filePath
	 *            文件路径
	 * @return 存在返回true，否则返回false
	 */
	public static boolean isExist(String filePath) {
		return new File(filePath).exists();
	}

	/**
	 * 将字符串写入指定文件(当指定的父路径中文件夹不存在时，会最大限度去创建，以保证保存成功！)
	 *
	 * @param res
	 *            原字符串
	 * @param filePath
	 *            文件路径
	 * @return 成功标记
	 */
	public static boolean string2File(String res, String filePath) {
		boolean flag = true;
		BufferedReader bufferedReader = null;
		BufferedWriter bufferedWriter = null;
		try {
			File distFile = new File(filePath);
			if (!distFile.getParentFile().exists())
				distFile.getParentFile().mkdirs();
			bufferedReader = new BufferedReader(new StringReader(res));
			bufferedWriter = new BufferedWriter(new FileWriter(distFile));
			char buf[] = new char[1024]; // 字符缓冲区
			int len;
			while ((len = bufferedReader.read(buf)) != -1) {
				bufferedWriter.write(buf, 0, len);
			}
			bufferedWriter.flush();
			bufferedReader.close();
			bufferedWriter.close();
		} catch (IOException e) {
			flag = false;
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 获取某个目录其下的子目录，不递归遍历子孙目录
	 * @param dir 需要获取的目录
	 * @return
	 */
	public static ArrayList<String> getSubDirs(String dir){
		if (StringUtils.isBlank(dir)){
			return null;
		}

		File file = new File(dir);
		if (!file.isDirectory()){
			return null;
		}

		String separator = dir.substring(dir.length()-1, dir.length());
		if (separator.equals(File.separator)){
			separator = "";
		}else{
			separator = File.separator;
		}
		ArrayList<String> list = new ArrayList<String>();
		File[] subFile = file.listFiles();
		for (int i = 0; i < subFile.length; i++) {
			if (subFile[i].isDirectory()) {
				list.add(dir+separator+subFile[i].getName());
			}
		}
		return list;
	}

	/**
	 * 获取目录下所有文件列表（递归子目录）
	 * @param dir 目录
	 * @param files 接收返回列表对象
	 */
	public static void listFile(File dir, ArrayList<String> files){
		if(dir.isDirectory()){
			File[] fileList = dir.listFiles();
			for (File file2 : fileList) {
				listFile(file2, files);
			}
		}else{
			files.add(dir.getAbsolutePath());
		}
	}

	/**
	 * 获取目录下所有文件列表（递归子目录）
	 * @param dir 目录
	 * @param files 接收返回列表对象
	 */
	public static void listFile(String dir, ArrayList<String> files){
		File file = new File(dir);
		listFile(file, files);
	}






	/**
	 * 从一个全路径文件名获取文件名称
	 * @param pathName 全路径文件名
	 * @return
	 */
	public static String getFileName(String pathName){
		int pos = pathName.lastIndexOf(File.separator);
		int len = pathName.length();
		return pathName.substring(pos+ File.separator.length(), len);
	}

	/**
	 * 获取回车换行符
	 * @return
	 */
	public static String getCRLF(){
		return System.getProperty("line.separator");
	}

	/**
     * 获取文件扩展名
     * @param file
     * @return
     */
    public static String getFileExtension(File file) {
        String fileName = file.getName();
        return getFileExtension(fileName);
    }

    /**
     * 获取文件扩展名
     * @param fileName
     * @return
     */
    public static String getFileExtension(String fileName) {
    	if (StringUtils.isBlank(fileName)){
    		return "";
    	}
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
            return "";
        }
    }

	/**
	 * 将文件路径名转换成本机文件路径名
	 * @return 本机文件路径名
	 */
	public static String fileNameConvert(String path){
		if (path == null || path.length() == 0) {
			return path;
		}
		if (path.indexOf("\\") > -1) {
			path = path.replace('\\', File.separatorChar);
			if (path.indexOf("/") > -1) {
				return path.replace('/', File.separatorChar);
			}
			return path ;
		}else if (path.indexOf("/") > -1) {
			return path.replace('/', File.separatorChar);
		}
		return path;
	}
	/**
	 * 读取文件内容 返回字符串
	 * @param fileName
	 * @return
	 */
	public static String readFileContent(String fileName) {
		File file = new File(fileName);
		BufferedReader reader = null;
		StringBuffer sbf = new StringBuffer();
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempStr;
			while ((tempStr = reader.readLine()) != null) {
				sbf.append(tempStr);
			}
			reader.close();
			return sbf.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return sbf.toString();
	}

	/**
	 *  压缩单个excel文件的输出流 到zip输出流,注意zipOutputStream未关闭，需要交由调用者关闭之
	 * @param zipOutputStream zip文件的输出流
	 * @param excelOutputStream excel文件的输出流
	 * @param excelFilename 文件名可以带目录，例如 TestDir/123.xls
	 */
	public static void compressFileToZipStream(ZipOutputStream zipOutputStream,
                                               ByteArrayOutputStream excelOutputStream, String excelFilename) {
		byte[] buf = new byte[1024];
		try {
			// Compress the files
			byte[] content = excelOutputStream.toByteArray();
			ByteArrayInputStream is = new ByteArrayInputStream(content);
			BufferedInputStream bis = new BufferedInputStream(is);
			// Add ZIP entry to output stream.
			zipOutputStream.putNextEntry(new ZipEntry(excelFilename));
			// Transfer bytes from the file to the ZIP file
			int len;
			while ((len = bis.read(buf)) > 0) {
				zipOutputStream.write(buf, 0, len);
			}
			// Complete the entry
			//excelOutputStream.close();//关闭excel输出流
			zipOutputStream.closeEntry();
			bis.close();
			is.close();
			// Complete the ZIP file
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
